#include <boost/asio.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/asio/buffer.hpp>
#include <vector>

using boost::asio::ip::tcp;
using boost::asio::io_service;

typedef boost::shared_ptr<tcp::socket> socket_ptr;

class client {
public:
	client(io_service &io) : ios(io),
		ep(boost::asio::ip::address::from_string("127.0.0.1"), 6698) 
	{
		start();
	}

private:
	void start()
	{
		socket_ptr sock(new tcp::socket(ios));
		sock->async_connect(ep, 
			bind(&client::conn_handler, this, boost::asio::placeholders::error, sock));
	}

	void conn_handler(const boost::system::error_code &ec, socket_ptr sock) 
	{
		if (ec) {
			std::cout << "conn_handler error!!!" << std::endl;
			return;
		}

		std::cout << "recieve from: " << sock->remote_endpoint().address() << "... ";
		boost::shared_ptr<std::vector<unsigned char> > str(new std::vector<unsigned char>(512, 0));
		sock->async_read_some(boost::asio::buffer(*str), 
			bind(&client::read_handler, this, boost::asio::placeholders::error, str));

		//start();
	}

	void read_handler(const boost::system::error_code &ec, boost::shared_ptr<std::vector<unsigned char> > str) 
	{
		if (ec) {
			std::cout << "read_handler error!!!" << std::endl;
			return;
		}

		std::cout << &(*str)[0] << std::endl;
	}

private:
	io_service &ios;
	tcp::endpoint ep;
};

int main(int argc, char* argv[]) 
{
	try {
		std::cout << "client start." << std::endl;
		io_service ios;
		client cl(ios);
		ios.run();
	} catch (std::exception &e) {
		std::cout << e.what() << std::endl;
	}

	return 0;
}
